平台的二进制接口不仅定义了参数的传递方式，还包括如何布局堆栈帧:哪里存储局部变量，将寄存器溢出到哪里等。函数的开始和结束处需要一个特殊的指令序列，称为序言和尾声。当前的开发状态下，目标不支持创建序言和尾部声明的机器指令，但用于指令选择的帧代码要求TargetFrameLowering的子类可用。简单的解决方案是为M88kFrameLowering类提供一个空的实现。

该类的声明在M88kFrameLowering.h文件中，我们要做的就是重写纯虚函数:

\begin{cpp}
namespace llvm {
class M88kFrameLowering : public TargetFrameLowering {
public:
    M88kFrameLowering();

    void
    emitPrologue(MachineFunction &MF,
    MachineBasicBlock &MBB) const override;

    void
    emitEpilogue(MachineFunction &MF,
                 MachineBasicBlock &MBB) const override;
    bool hasFP(const MachineFunction &MF) const override;
};
}
\end{cpp}

该实现存储在M88kFrameLowering.cpp文件中，提供了关于构造函数中堆栈帧的一些基本细节。堆栈向下扩展到更小的地址，并以8字节的边界对齐。当调用函数时，局部变量直接存储在调用函数的堆栈指针下面，因此局部区域的偏移量为0。即使在函数调用期间，堆栈也应该保持在8字节的边界上对齐。最后一个参数表示不能重新排列堆栈。其他函数只有一个空实现:

\begin{cpp}
M88kFrameLowering::M88kFrameLowering()
    : TargetFrameLowering(
        TargetFrameLowering::StackGrowsDown, Align(8),
        0, Align(8), false /* StackRealignable */) {}

void M88kFrameLowering::emitPrologue(
    MachineFunction &MF, MachineBasicBlock &MBB) const {}

void M88kFrameLowering::emitEpilogue(
    MachineFunction &MF, MachineBasicBlock &MBB) const {}

bool M88kFrameLowering::hasFP(
    const MachineFunction &MF) const { return false; }
\end{cpp}

当然，随着我们的实现的增长，这个类将是第一个需要完全实现的类。

将所有部件组装在一起之前，需要实现汇编输出器，用于生成机器指令。

















































